package org.yu.register.machine;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.items.CapabilityItemHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.yu.api.blocks.data.BlockFacingFor4Side;
import org.yu.api.util.LazyUtil;
import org.yu.register.MachineRegistry;

import javax.annotation.ParametersAreNonnullByDefault;

@ParametersAreNonnullByDefault
public class StoveBlock extends BlockFacingFor4Side implements EntityBlock {
    public static final BooleanProperty LIT = BlockStateProperties.LIT;

    public StoveBlock(Properties properties) {
        super(properties);
        BlockState blockState = this.stateDefinition.any()
                .setValue(FACING, Direction.NORTH)
                .setValue(LIT,false);
        registerDefaultState(blockState);
    }

    @Override
    protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> pBuilder) {
        pBuilder.add(FACING).add(LIT);
    }

    @Nullable
    @Override
    public BlockState getStateForPlacement(BlockPlaceContext pContext) {
        return defaultBlockState()
                .setValue(FACING, pContext.getHorizontalDirection().getOpposite())
                .setValue(LIT,false);
    }

    @Nullable
    @Override
    public BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) {
        return MachineRegistry.stoveBlockEntity.create(pPos, pState);
    }

    @Nullable
    @Override
    public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level pLevel, BlockState pState, BlockEntityType<T> pBlockEntityType) {
        return LazyUtil.getTicker();
    }
    @NotNull
    @Override
    public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, BlockHitResult pHit) {
        if(pLevel.isClientSide)return InteractionResult.SUCCESS;
        var be= pLevel.getBlockEntity(pPos);
        if(be==null)return InteractionResult.FAIL;
        be.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).ifPresent(iItemHandler -> {
            var item=iItemHandler.getStackInSlot(0);
            var handItem=pPlayer.getItemInHand(pHand);
            if(item.isEmpty()&&!handItem.isEmpty()){
                if(iItemHandler.isItemValid(0,handItem)) {
                    iItemHandler.insertItem(0, handItem.copy(), false);
                    pPlayer.setItemInHand(pHand, ItemStack.EMPTY);
                }
            }else if(!item.isEmpty()&&handItem.isEmpty()&&pPlayer.isShiftKeyDown()){
                pPlayer.addItem(iItemHandler.extractItem(0,item.getCount(),false));
            }
        });
        return InteractionResult.SUCCESS;
    }
    @Override
    public void neighborChanged(BlockState pState, Level pLevel, BlockPos pPos, Block pBlock, BlockPos pFromPos, boolean pIsMoving) {
        this.checkPoweredState(pLevel, pPos);
    }

    private void checkPoweredState(Level pLevel, BlockPos pPos) {
        boolean flag = pLevel.hasNeighborSignal(pPos);
            var be=pLevel.getBlockEntity(pPos);
            if(be instanceof StoveBlockEntity stoveBlockEntity){
                stoveBlockEntity.setOpen(!flag);
            }
    }
}
